///////////////////////////////////////////////////////////////////////
//
//
//        FILE      :   BaseThread.h
//        PURPOSE   :   Thread wrap
//
//        AUTHOR    :   AX
//        DATE      :   2008/08/01
//
//
//
// how to use:
//
// 1. thread owner write a function named Run,proto is  int  Run(void* lparam);
//     do not need static declare
// 2. thread owner has a member named m_cBaseThread with " BaseThread<OWNER>" type,do not use pointer;
//
// 3. thread owner call m_cBaseThread.Start(param) at nessary place
//
//////////////////////////////////////////////////////////////////////
#ifndef __BASE_THREAD_H__
#define __BASE_THREAD_H__
#include "os.h"
template <typename T>
class BaseThread
{
public:
	BaseThread(T& t):m_T(t)
	{
		m_hThread = 0;

	}

	virtual  ~BaseThread()
	{
		Stop();

	}
private:

	typedef struct _tagTThreadParam
	{
		void* lparam;

		BaseThread*  pThread;

	}TThreadParam;



public:


	int Start(void* lparam)
	{
		if(m_hThread)
			return 0;

		TThreadParam&  tParam = m_tParam;

		tParam.pThread = this;
		tParam.lparam  = lparam;

		m_hThread = OS_ThreadCreate(ThreadFunc,
			OS_THREAD_PRIORITY_NORMAL,
			OS_THREAD_STACK_NORMAL,&tParam);

		if(m_hThread)
			return 0;

		return -1;

	}


	void Stop()
	{
		m_T.Stop();

		if(m_hThread == 0)
			return;

		OS_ThreadJoin(m_hThread);
		OS_ThreadDestroy(m_hThread);

		m_hThread = 0;

	}





private:

	pthread_t    m_hThread;

	static THREAD_START ThreadFunc(void* lparam)
	{
		if(lparam == NULL)
			return (THREAD_START)0;
		TThreadParam* pParam = (TThreadParam*)lparam;

		BaseThread* pThread = pParam->pThread;

		if(pThread == NULL)
			return (THREAD_START)0;

		pThread->m_T.Run(pParam->lparam);

		return (THREAD_START)0;

	}


	T&           m_T;
	TThreadParam  m_tParam;

};


#endif
/////example/////////////////////////////////////////////
//
//class ThreadOwner
//{
//
//public:
//   THREAD_START  Run(void* lparam);
//
//   void  UnInit();
//  protected:
//     BaseThread<ThreadOwner>  m_cBaseThread;
//
//}
// 
// or 
//
//  class ThreadOwner: public BaseThread<ThreadOwner>

//
//
//
//
//
//
//
//
